<?php

namespace controller\admin;

defined('IA_ROOT') || exit();

use mvc\Controller;
use facade\Model;
use facade\View;
use facade\Util;

class Base extends Controller
{
    // 基址
    protected $site_url;
    protected $subdir;

    // 语言
    protected $langs;
    protected $lang;

    // 用户角色权限
    protected $user;
    protected $role;
    protected $auth;

    // 模块控制器方法
    protected $module;
    protected $controller;
    protected $action;

    // 系统设置
    protected $setting;

    // 初始化
    protected function initialize()
    {
        // 登录认证
        !session_id() && session_start();
        $this->site_url = Util::url();
        $this->subdir = Util::subdir();
        $this->langs = Util::langs();
        $this->lang = Util::lang();
        $ip = Util::getIp();
        if (!isset($_SESSION['uid']) || empty($_SESSION['uid'])) {
            if (!isset($_COOKIE['token']) || empty($_COOKIE['token'])) {
                Util::config('log') && Model::insert('log', ['author' => Util::tran('匿名'), 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('非法访问'), 'message' => Util::tran('未登录访问后台'), 'ip' => $ip, 'status' => 1, 'time' => time()]);
                Util::errMsg(['code' => 1, 'msg' => Util::tran('请先登录'), 'url' => Util::url($this->lang == 'zh-CN' ? "/admin/login.html" : "/{$this->lang}/admin/login.html")]);
            }
            $this->user = Model::fetch("SELECT * FROM `user` WHERE `remember_token`=:token ORDER BY `id` ASC LIMIT 1", [':token' => $_COOKIE['token']]);
            if (!$this->user) {
                Util::config('log') && Model::insert('log', ['author' => Util::tran('匿名'), 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('非法访问'), 'message' => Util::tran('Cookie无效或过期'), 'ip' => $ip, 'status' => 1, 'time' => time()]);
                Util::errMsg(['code' => 1, 'msg' => Util::tran('请先登录'), 'url' => Util::url($this->lang == 'zh-CN' ? "/admin/login.html" : "/{$this->lang}/admin/login.html")]);
            }
            $_SESSION['uid'] = $this->user['id'];
        }
        if (!$this->user) {
            $this->user = Model::fetch("SELECT * FROM `user` WHERE `id`=:id ORDER BY `id` ASC LIMIT 1", [':id' => $_SESSION['uid']]);
        }
        if (!$this->user) {
            Util::config('log') && Model::insert('log', ['author' => Util::tran('匿名'), 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('非法访问'), 'message' => Util::tran('Session无效或过期'), 'ip' => $ip, 'status' => 1, 'time' => time()]);
            Util::errMsg(['code' => 1, 'msg' => Util::tran('请先登录'), 'url' => Util::url($this->lang == 'zh-CN' ? "/admin/login.html" : "/{$this->lang}/admin/login.html")]);
        }

        // 检查单点登录
        $this->setting = $this->setting();
        if ($this->setting['alone_login']) {
            $randstr = isset($_COOKIE['randstr']) ? $_COOKIE('randstr') : false;
            $cache_randstr = Util::getCache('rand' . $this->user['id']);
            if ($randstr !== $cache_randstr) {
                unset($_SESSION['uid']);
                setcookie('token', '', time() - 3600, '/');
                Util::errMsg(['code' => 1, 'msg' => Util::tran('您的账号已在别处登录，请重新登录！'), 'url' => Util::url($this->lang == 'zh-CN' ? "/admin/login.html" : "/{$this->lang}/admin/login.html")]);
            }
        }

        // 获取当前模块-控制器-方法
        $this->module = Util::module();
        $this->controller = Util::controller();
        $this->action = Util::action();

        // 用户-角色-权限认证
        $this->role = Model::fetchAll("SELECT * FROM `role` ORDER BY `sort` DESC, `id` ASC");
        $this->auth = Model::fetchAll("SELECT * FROM `auth` ORDER BY `sort` DESC, `id` ASC");
        $_role = array_filter($this->role, function ($item) {
            return $item['id'] === $this->user['role_id'];
        });
        $_role = array_shift($_role);
        if (!$_role) {
            Util::config('log') && Model::insert('log', ['author' => $this->user['username'], 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('拒绝访问'), 'message' => Util::tran('角色不存在'), 'ip' => $ip, 'status' => 1, 'time' => time()]);
            Util::errMsg(Util::tran('角色不存在，请联系管理员'));
        }
        if (1 == $_role['status']) {
            Util::config('log') && Model::insert('log', ['author' => $this->user['username'], 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('拒绝访问'), 'message' => Util::tran('角色被禁用'), 'ip' => $ip, 'status' => 1, 'time' => time()]);
            Util::errMsg(Util::tran('角色被禁用，请联系管理员'));
        }
        $_auth = array_filter($this->auth, function ($item) {
            return $item['controller'] === $this->controller && $item['action'] === $this->action;
        });
        $_auth = array_shift($_auth);
        if (!$_auth) {
            Util::config('log') && Model::insert('log', ['author' => $this->user['username'], 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('拒绝访问'), 'message' => Util::tran('功能不存在'), 'ip' => $ip, 'status' => 1, 'time' => time()]);
            Util::errMsg(Util::tran('功能不存在，请联系管理员'));
        }
        if (1 == $_auth['status']) {
            Util::config('log') && Model::insert('log', ['author' => $this->user['username'], 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('拒绝访问'), 'message' => Util::tran('功能被禁用'), 'ip' => $ip, 'status' => 1, 'time' => time()]);
            Util::errMsg(Util::tran('功能被禁用，请联系管理员'));
        }
        $_auth_ids = (array)json_decode($_role['auth_ids'], true);
        if (!in_array($_auth['id'], $_auth_ids)) {
            Util::config('log') && Model::insert('log', ['author' => $this->user['username'], 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => Util::tran('拒绝访问'), 'message' => Util::tran('没有权限'), 'ip' => $ip, 'status' => 1, 'time' => time()]);
            Util::errMsg(Util::tran('没有权限，请联系管理员'));
        }
        $_lang_slugs = $this->user['lang_slugs'] ? json_decode($this->user['lang_slugs'], true) : [];
        $_role['auth_ids'] = $_auth_ids;
        $this->user['role'] = $_role;
        $this->user['auth'] = $_auth;
        $this->user['langs'] = $_lang_slugs;

        // 本地化公共语言串
        View::assign('lang', $this->lang);
        View::assign('site_url', $this->site_url);
        View::assign(['module' => $this->module, 'controller' => $this->controller, 'action' => $this->action]);
        View::assign('localize', [
            'backend' => Util::tran('管理后台'),
            'choice_row' => Util::tran('请选择行数据'),
            'delall_confirm' => Util::tran('真的删除选中的行吗？'),
            'delall' => Util::tran('批量删除'),
            'destroy_all_confirm' => Util::tran('真的彻底删除选中的行吗？'),
            'destroy_all' => Util::tran('彻底删除'),
            'restore_all_confirm' => Util::tran('真的还原选中的行吗？'),
            'restore_all' => Util::tran('批量还原'),
            'pending_all_confirm' => Util::tran('真的待审核选中的行吗？'),
            'pending_all' => Util::tran('批量待审'),
            'passed_all_confirm' => Util::tran('真的审核通过选中的行吗？'),
            'passed_all' => Util::tran('批量审核'),
            'spam_all_confirm' => Util::tran('真的标记垃圾评论选中的行吗？'),
            'spam' => Util::tran('垃圾评论'),
            'add' => Util::tran('添加'),
            'upload' => Util::tran('上传'),
            'ok' => Util::tran('确定'),
            'cancel' => Util::tran('取消'),
            'jump' => Util::tran('跳转'),
            'page_num' => Util::tran('页码'),
            'total' => Util::tran('共计'),
            'per_page' => Util::tran('每页'),
            'first_page' => Util::tran('第一页'),
            'last_page' => Util::tran('最后页'),
            'filter_column' => Util::tran('筛选列'),
            'export' => Util::tran('导出'),
            'print' => Util::tran('打印'),
            'calc_file_confirm' => Util::tran('计算孤立文件需要较长时间，确定继续吗？'),
            'calc_file' => Util::tran('计算孤立文件'),
            'del_row_confirm' => Util::tran('真的删除行么？'),
            'del_row' => Util::tran('删除行'),
            'del_rows_confirm' => Util::tran('真的删除行或子行么？'),
            'restore_row_confirm' => Util::tran('真的还原行么？'),
            'restore_row' => Util::tran('还原行'),
            'choose' => Util::tran('请选择'),
            'input' => Util::tran('请输入'),
            'reply' => Util::tran('回复'),
            'edit' => Util::tran('编辑'),
            'path' => Util::tran('路径'),
            'preview' => Util::tran('预览'),
            'name' => Util::tran('名称'),
            'rename' => Util::tran('重命名'),
            'title' => Util::tran('标题'),
            'category' => Util::tran('分类'),
            'tag' => Util::tran('标签'),
            'slug' => Util::tran('别名'),
            'description' => Util::tran('描述'),
            'untitled' => Util::tran('标题或名称不能为空'),
            'editor_empty' => Util::tran('编辑器内容为空'),
            'lines' => Util::tran('行数'),
            'info' => Util::tran('信息'),
            'i18n' => Util::tran('国际化'),
            'expect' => Util::tran('期望'),
            'auto' => Util::tran('自动'),
            'block' => Util::tran('块'),
            'but_found' => Util::tran('但发现'),
            'i18n_help' => Util::tran('国际化帮助'),
            'i18n_slug_empty' => Util::tran('源语言别名为空，不能国际化'),
            'can_not_calc_status' => Util::tran('文件有在使用中，请重新计算状态'),
            'no_text_selected' => Util::tran('未选择文本'),
            'select_line_text' => Util::tran('未选择整行文本'),
            'select_none' => Util::tran('请选择划词'),
            'select_err' => Util::tran('划词选择错误'),
            'select_line_err' => Util::tran('划词选择行错误'),
            'source_data_changed' => Util::tran('数据源发生改变'),
            'fill_success' => Util::tran('填充成功，行号'),
            'fetch_source_data' => Util::tran('请提取语言包'),
            'fetch_no_empty_line' => Util::tran('目标语言包未发现空行'),
            'no_voice_text' => Util::tran('没有语音文字'),
            'no_voice_support' => Util::tran('该语言不支持语音朗读'),
            'select_voice_lang' => Util::tran('请选择一种语言朗读'),
            'voice_reading_finished' => Util::tran('语音朗读完成'),
            'please_select_language' => Util::tran('请选择语言'),
            'request_time_out' => Util::tran('请求超时'),
            'close_sort_error' => Util::tran('闭合顺序错误'),
            'unclosed_tag' => Util::tran('未闭合标签'),
            'found_dismatch_close_tag' => Util::tran('发现未匹配的闭合标签'),
            'please_first_complete_i18n' => Util::tran('请先完成国际化'),
        ]);
    }

    // 继承方法
    // 系统设置
    protected function setting($field = '')
    {
        static $setting;
        $default = [
            'webLogo' => '/static/images/brand.png',
            'webName' => 'Brand',
            'seo_title' => '',
            'seo_description' => '',
            'upload_type' => 'gif|jpg|jpeg|png|mp3|mp4|zip',
            'upload_size' => '2048',
            'robot_index' => '0',
            'alone_login' => '0',
            'copyright' => '&copy; 2021-' . date('Y') . ' Company, Inc.',
            'icp' => 'ICP No.001',
            'cdn_speed' => '0',
            'slide_image_1' => '',
            'slide_url_1' => '',
            'slide_image_2' => '',
            'slide_url_2' => '',
            'slide_image_3' => '',
            'slide_url_3' => '',
            'slide_image_4' => '',
            'slide_url_4' => '',
            'slide_image_5' => '',
            'slide_url_5' => '',
            'hot_num' => '5',
            'comm_num' => '5',
            'related_num' => '3',
            'page_num' => '24',
            'link_num' => 8,
            'voice_read' => '1',
            'can_comment' => '1',
            'pending_comment' => '1',
            'service' => '',
            'email' => '',
            'code' => '',
            'static' => '',
            'date' => '',
            'site' => '',
        ];
        if ($field == 'default')
            return $default;
        if ($setting === null) {
            $setting = Model::fetch('SELECT * FROM `setting` WHERE id=:id', [':id' => 1]);
            if ($setting) {
                $setting = json_decode($setting['value'], true);
                $setting = array_intersect_key($setting, $default);
                $setting = array_merge($default, $setting);
            } else {
                $setting = $default;
            }
        }
        foreach ($setting as $key => $value) {
            if (substr($value, 0, 1) == '/' && preg_match('#(/static/[^\.]+\.(gif|jpe?g|png|bmp|webp|psd|svg|tiff))#i', $value, $match)) {
                $setting[$key] = $this->subdir . $match[1];
            }
        }
        if ($field)
            return $setting[$field];
        return $setting;
    }

    // 格式化树
    protected function format_tree($data, $field = 'name')
    {
        $data = Util::trees($data);
        $data = array_map(function ($item) use ($field) {
            $item['tree_' . $field] = $item['level'] ? str_repeat("&nbsp;&nbsp;&nbsp;", $item['level']) . "┠ " . $item[$field] : $item[$field];
            return $item;
        }, $data);
        return $data;
    }

    // 媒体图标
    protected function ico($ext)
    {
        $ico = ['ai', 'dir', 'fonts', 'mm', 'pages', 'txt', 'zip', 'apk', 'doc', 'ipa', 'mmap', 'pdf', 'visio', 'bt', 'eps', 'keynote', 'mp3', 'ppt', 'web', 'cad', 'exe', 'links', 'mp4', 'ps', 'xls', 'code', 'fla', 'misc', 'number', 'rar', 'xmind'];
        if (in_array($ext, $ico)) {
            if (is_file(IA_ROOT . '/static/res/layui_exts/ico/' . $ext . '.png')) {
                return $this->site_url . '/static/res/layui_exts/ico/' . $ext . '.png';
            }
        }
        return '';
    }

    // 系统日志
    protected function log($title = '', $message = '', $status = 0)
    {
        Util::config('log') && Model::insert('log', ['author' => $this->user['username'], 'request_method' => Util::requestMethod(), 'url' => htmlentities($_SERVER['REQUEST_URI']), 'title' => $title, 'message' => mb_strimwidth($message, 0, 250, '...', 'UTF-8'), 'ip' => Util::getIp(), 'status' => $status, 'time' => time()]);
    }
}
